package utils;

import java.util.ArrayList;
import java.util.HashSet;

import models.cards.CityCard;
import models.cards.IPlayerCard;
import models.city.City;
import models.desease.Disease;
import models.game.Game;
import models.players.Player;

public abstract class PlayerValidationAndOptions {

	private static boolean playerHasCityCards(Player player) {
		for (IPlayerCard card : player.getHand().values()) {
			if (card instanceof CityCard) {
				return true;
			}
		}
		return false;
	}

	private static boolean playerHasFiveSameDiseaseCards(Player player,
			Disease disease) {
		int count = 5;
		for (IPlayerCard card : player.getHand().values()) {
			if (card instanceof CityCard) {
				if (((CityCard) card).getDisease().equals(disease)) {
					count--;
				}
			}
			if (count == 0) {
				return true;
			}
		}
		return false;
	}

	public static HashSet<Player> playersWithSameLocation(Player player, Game game) {
		HashSet<Player> players = new HashSet<Player>();

		for (Player otherPlayer : game.getPlayers().values()) {
			if (!(player.equals(otherPlayer))) {
				if (player.getLocation().equals(otherPlayer.getLocation())) {
					players.add(otherPlayer);
				}
			}
		}
		return players;
	}

	public static boolean canDrive(Player player, Game game) {
		return true;
	}

	public static boolean canDirectFlight(Player player, Game game) {
		return playerHasCityCards(player);
	}

	public static boolean canCharterFlight(Player player, Game game) {
		if (player.getHand().containsKey(player.getLocation().getName())) {
			return true;
		}
		return false;
	}

	public static boolean canShuttleFlight(Player player, Game game) {
		if (player.getLocation().getHasResearchCentre() == true) {
			for (City city : game.getCities().values()) {
				if (!player.getLocation().equals(city)
						&& city.getHasResearchCentre() == true) {
					return true;
				}
			}
		}
		return false;
	}

	public static boolean canBuildReserachStation(Player player, Game game) {
		if (player.getLocation().getHasResearchCentre() == false) {
			if (player.getHand().containsKey(player.getLocation().getName())) {
				return true;
			}
		}
		return false;
	}

	public static boolean canTreatDisease(Player player, Game game) {
		if (player.getLocation().getInfectionLevel() > 0) {
			return true;
		}
		return false;
	}

	public static boolean canDiscoverACure(Player player, Game game) {
		if (player.getLocation().getHasResearchCentre() == true) {
			for (Disease disease : game.getDiseases().values()) {
				if (disease.getIsCured() == false) {
					if (playerHasFiveSameDiseaseCards(player, disease)) {
						return true;
					}
				}
			}
		}
		return false;
	}

	public static boolean canRecieveKnowledge(Player player, Game game) {
		for (Player otherPlayer : playersWithSameLocation(player, game)) {
			if (otherPlayer.getHand().containsKey(player.getLocation().getName())) {
				return true;
			}
		}
		return false;
	}

	// for testing
	//
	// public static boolean canRecieveKnowledge(Player player, Game game) {
	// for (Player otherPlayer : playersWithSameLocation(player, game)) {
	// if (playerHasCityCards(otherPlayer)) {
	// return true;
	// }
	// }
	// return false;
	// }

	public static boolean canShareKnowledge(Player player, Game game) {
		HashSet<Player> players = playersWithSameLocation(player, game);
		if (!players.isEmpty() && player.getHand().containsKey(player.getLocation().getName())) {
			return true;
		}
		return false;
	}

	public static ArrayList<String> driveOpitions(Player player, Game game) {
		ArrayList<String> list = new ArrayList<String>();
		list.addAll(player.getLocation().getNeighbourNames());
		return list;
	}

	public static ArrayList<String> directFlightOpitions(Player player, Game game) {
		ArrayList<String> list = new ArrayList<String>();
		for (IPlayerCard card : player.getHand().values()) {
			if (card instanceof CityCard) {
				if (!((CityCard) card).getCity().equals(player.getLocation())) {
					list.add(card.getName());
				}
			}
		}
		return list;
	}

	public static ArrayList<String> charterFlightOpitions(Player player, Game game) {
		ArrayList<String> list = new ArrayList<String>();
		for (City city : game.getCities().values()) {
			if (!city.equals(player.getLocation())) {
				list.add(city.getName());
			}
		}
		return list;
	}

	public static ArrayList<String> shuttleFlightOpitions(Player player, Game game) {
		ArrayList<String> list = new ArrayList<String>();
		for (City city : game.getCities().values()) {
			if (!city.equals(player.getLocation())
					&& city.getHasResearchCentre()) {
				list.add(city.getName());
			}
		}
		return list;
	}

	public static ArrayList<String> buildResearchStationOpitions(Player player, Game game) {
		ArrayList<String> list = new ArrayList<String>();
		list.add("Confirm");
		return list;
	}

	public static ArrayList<String> treatDiseaseOpitions(Player player, Game game) {
		ArrayList<String> list = new ArrayList<String>();
		list.add("Confirm");
		return list;
	}

	public static ArrayList<String> discoverACureOpitions(Player player, Game game) {
		ArrayList<String> list = new ArrayList<String>();
		for (Disease disease : game.getDiseases().values()) {
			if (playerHasFiveSameDiseaseCards(player, disease)) {
				list.add(disease.getName());
			}
		}
		return list;
	}

	public static ArrayList<String> recieveKnowledgeOptions(Player player, Game game) {
		ArrayList<String> list = new ArrayList<String>();
		list.add(player.getLocation().getName());
		return list;
	}
	
	public static ArrayList<String> shareKnowledgeOptions(Player player, Game game) {
		ArrayList<String> list = new ArrayList<String>();
		for(Player otherPlayer : playersWithSameLocation(player, game)) {
			list.add(otherPlayer.getUsername());
		}
		return list;
	}

	// for testing
	// public static ArrayList<String> recieveKnowledgeOptions(Player player, Game game) {
	// ArrayList<String> list = new ArrayList<String>();
	// for (Player otherPlayer : playersWithSameLocation(player, game)) {
	// for (IPlayerCard card : otherPlayer.getHand().values()) {
	// if (card instanceof CityCard) {
	// list.add(card.getName());
	// }
	// }
	// }
	// return list;
	// }

}
